<template>
  <div class="clean-page">
    <div class="header">
      <img src="/logo_02.png" alt="系统Logo" class="system-logo" />
      <h2>文本清洗</h2>
    </div>

    <div class="layout">
      <!-- 左侧：清洗参数与操作 -->
      <el-card class="panel panel-params">
        <template #header>
          <div class="panel-title">清洗参数设置</div>
        </template>

        <div class="param-row">
          <div class="param-item">
            <div class="param-label">清理特殊字符</div>
            <el-switch v-model="options.removeSpecial" />
          </div>
          <div class="param-item">
            <div class="param-label">删除重复项</div>
            <el-switch v-model="options.dropDuplicates" />
          </div>
        </div>

        <div class="divider"></div>

        <div class="upload-area">
          <el-upload
            drag
            action="#"
            :auto-upload="false"
            :show-file-list="false"
            :on-change="handleFileChange"
            accept=".txt,.csv,.json"
            class="upload-drop"
          >
            <el-icon class="upload-icon"><UploadFilled /></el-icon>
            <div class="upload-tip">点击或拖拽文件</div>
            <div class="upload-subtip">支持 .txt格式</div>
          </el-upload>

          <div v-if="selectedFileName" class="file-info">
            已选择文件：{{ selectedFileName }}
          </div>

          <el-button
            class="btn-primary"
            type="primary"
            @click="handleClean"
            :loading="cleaning"
            :disabled="!file || cleaning"
          >
            开始清洗
          </el-button>

          <div v-if="cleaning" class="loading-indicator">
            <el-icon><Loading /></el-icon>
            正在清洗文本，请稍候...
          </div>
        </div>
      </el-card>

      <!-- 右侧：结果统计与占位 -->
      <el-card class="panel panel-result">
        <template #header>
          <div class="panel-title">清洗结果统计</div>
        </template>

        <div v-if="cleanedResult" class="stats">
          <div class="stat-item">
            <div class="stat-value">{{ cleanedResult.total_lines || 0 }}</div>
            <div class="stat-label">总行数</div>
          </div>
          <div class="stat-item">
            <div class="stat-value accent">{{ cleanedResult.cleaned_lines || 0 }}</div>
            <div class="stat-label">清洗后行数</div>
          </div>
          <div class="stat-item">
            <div class="stat-value">{{ cleanedResult.invalid_lines || 0 }}</div>
            <div class="stat-label">移除无效行</div>
          </div>
        </div>

        <div v-else class="placeholder">
          <div class="placeholder-box">总行数</div>
          <div class="placeholder-box">清洗后行数</div>
          <div class="placeholder-box">移除无效行</div>
        </div>

        <!-- 清洗结果预览 -->
        <div v-if="cleanedResult" class="preview">
          <div class="preview-header">清洗结果预览</div>
          <el-scrollbar class="preview-box" :max-height="260">
            <template v-if="previewFetching">
              <div class="preview-loading">
                <el-icon><Loading /></el-icon>
                正在载入预览...
              </div>
            </template>
            <template v-else>
              <pre v-if="previewText" class="preview-text">{{ previewText }}</pre>
              <div v-else class="preview-empty">暂无可预览内容，请使用下方按钮下载完整文件。</div>
            </template>
          </el-scrollbar>
        </div>

        <el-button
          class="btn-download"
          type="primary"
          @click="downloadCleanedResult"
          :disabled="!cleanedResult?.file_id"
        >
          下载清洗结果文件
        </el-button>
      </el-card>
    </div>

    <el-alert
      v-if="errorMessage"
      :title="errorMessage"
      type="error"
      show-icon
      closable
      @close="errorMessage = ''"
      class="error-alert"
    />
  </div>
  <div class="back-btn">
    <BackButton></BackButton>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import api from '@/api';
import { ElMessage } from 'element-plus'
import { Loading } from '@element-plus/icons-vue'
import { UploadFilled } from '@element-plus/icons-vue'
import BackButton from '@/components/BackButton.vue'
import '@/assets/common.css'

// 定义emit事件
const emit = defineEmits(['file-processed'])

// 状态管理
const file = ref(null)
const selectedFileName = ref('')
const cleaning = ref(false)
const cleanedResult = ref(null)
const errorMessage = ref('')
const previewText = ref('')
const previewFetching = ref(false)

// 清洗参数（仅前端展示与占位，后端如有对应参数，可在请求中附带）
const options = ref({
  removeSpecial: true,
  dropDuplicates: true,
  stopwordLang: 'zh'
})

// 处理文件选择
const handleFileChange = (fileObj) => {
  file.value = fileObj.raw
  selectedFileName.value = fileObj.name
  errorMessage.value = '' // 清除错误信息
}

// 处理文本清洗
const handleClean = async () => {
  if (!file.value) {
    ElMessage.error('请选择文件')
    return
  }

  cleaning.value = true
  errorMessage.value = ''

  try {
    const formData = new FormData()
    formData.append('file', file.value)
    // 如果后端支持参数，可追加：
    // formData.append('remove_special', String(options.value.removeSpecial))
    // formData.append('drop_duplicates', String(options.value.dropDuplicates))
    // formData.append('stopword_lang', options.value.stopwordLang)

    // 使用api模块而不是直接axios调用，确保路径正确
    const response = await api.post('/clean-text', formData, {
      // 让浏览器自动设置 multipart/form-data 的 boundary，避免预检失败
      timeout: 60000 // 1分钟超时
    })
    
    cleanedResult.value = response.data
    ElMessage.success('文本清洗完成')
    await fetchCleanPreview()
    
    // 触发文件处理完成事件
    emit('file-processed', response.data)
  } catch (error) {
    console.error('文本清洗失败:', error)
    // 更详细的错误信息显示
    if (error.response) {
      errorMessage.value = error.response.data?.error || `请求错误: ${error.response.status}`
    } else if (error.request) {
      errorMessage.value = '网络错误，请检查后端服务是否正常运行'
    } else {
      errorMessage.value = `请求配置错误: ${error.message}`
    }
  } finally {
    cleaning.value = false
  }
}

// 结果预览：从下载链接读取文本的前若干行
const fetchCleanPreview = async () => {
  try {
    previewFetching.value = true
    previewText.value = ''
    if (!cleanedResult.value?.file_id) return
    const url = `${api.defaults.baseURL}/download-cleaned/${cleanedResult.value.file_id}`
    const res = await fetch(url)
    const text = await res.text()
    // 限制预览大小，避免渲染压力
    const maxChars = 2000
    const limited = text.slice(0, maxChars)
    previewText.value = limited.split(/\r?\n/).slice(0, 100).join('\n')
  } catch (e) {
    previewText.value = ''
  } finally {
    previewFetching.value = false
  }
}

// 下载清洗结果
const downloadCleanedResult = async () => {
  try {
    // 使用api模块的基础URL来构建下载链接
    let downloadUrl = ''
    
    if (cleanedResult.value?.file_id) {
      downloadUrl = `${api.defaults.baseURL}/download-cleaned/${cleanedResult.value.file_id}`
    } else {
      downloadUrl = `${api.defaults.baseURL}/download-cleaned`
    }
    
    // 创建一个隐藏的a标签来下载文件
    const link = document.createElement('a')
    link.href = downloadUrl
    link.target = '_blank'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    
    ElMessage.success('文件下载开始')
  } catch (error) {
    console.error('下载失败:', error)
    ElMessage.error('文件下载失败，请稍后重试')
  }
}
</script>

<style scoped>
.clean-page {
  max-width: 1200px;
  margin: 0 auto;
  padding: 24px;
}

.header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
  color: #6f43ff; /* 紫色主色，参考站点图标色 */
}
.system-logo {
  width: 32px;
  height: 32px;
  object-fit: contain;
}

.layout {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: 16px;
}

.panel {
  border-radius: 12px;
  overflow: hidden;
}
.panel-title {
  font-weight: 600;
  color: #5b3cff;
}

.panel-params .el-card__header,
.panel-result .el-card__header {
  background: #f4f0ff;
}

.param-row {
  display: flex;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.param-item {
  flex:1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: #faf7ff;
  border: 1px dashed #e2dbff;
  padding: 10px 12px;
  border-radius: 10px;
}
.param-label {
  color: #6239ff;
  font-size: 14px;
}
.stopword-select {
  width: 140px;
}

.divider {
  height: 1px;
  background: #eee8ff;
  margin: 16px 0;
}

.upload-area {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}
.upload-drop {
  width: 100%;
}
.upload-icon {
  color: #6f43ff;
  font-size: 24px;
}
.upload-tip {
  color: #5e3fff;
  font-weight: 600;
  margin-top: 6px;
}
.upload-subtip {
  color: #8f8aa3;
  font-size: 12px;
}

.btn-primary {
  background: linear-gradient(90deg, #7b4dff 0%, #6a5bff 100%);
  border: none;
}
.btn-primary:focus,
.btn-primary:hover {
  filter: brightness(1.03);
}

.file-info {
  width: 100%;
  margin-top: 4px;
  padding: 10px 12px;
  background-color: #f6f3ff;
  border: 1px solid #ece7ff;
  border-radius: 8px;
  font-size: 14px;
  color: #5b5b66;
}

.loading-indicator {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #606266;
}

.panel-result .stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-bottom: 12px;
}
.stat-item {
  background: #faf7ff;
  border: 1px solid #eee8ff;
  border-radius: 10px;
  padding: 16px 12px;
  text-align: center;
}
.stat-value {
  font-size: 22px;
  font-weight: 700;
  color: #444;
}
.stat-value.accent {
  color: #6a5bff;
}
.stat-label {
  margin-top: 6px;
  color: #87839a;
  font-size: 12px;
}

.placeholder {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-bottom: 12px;
  text-align: center;
}
.placeholder-box {
  background: #f6f3ff;
  border: 1px dashed #e2dbff;
  border-radius: 10px;
  height: 88px;
  line-height: 88px;
}

.btn-download {
  width: 100%;
}

.error-alert {
  margin-top: 16px;
}

/* 预览模块样式 */
.preview {
  margin: 8px 0 12px;
}
.preview-header {
  font-weight: 600;
  color: #5b3cff;
  margin-bottom: 8px;
}
.preview-box {
  border: 1px solid #eee8ff;
  border-radius: 10px;
  background: #faf7ff;
}
.preview-text {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  font-size: 12px;
  line-height: 1.6;
  color: #3f3d56;
  padding: 12px 14px;
  white-space: pre-wrap;
  word-break: break-word;
}
.preview-empty,
.preview-loading {
  color: #7a7691;
  padding: 16px;
}


/* 响应式处理 */
@media (max-width: 1024px) {
  .layout {
    grid-template-columns: 1fr;
  }
  .panel-result .stats,
  .placeholder {
    grid-template-columns: repeat(3, 1fr);
  }
}
@media (max-width: 640px) {
  .param-row {
    grid-template-columns: 1fr;
  }
  .panel-result .stats,
  .placeholder {
    grid-template-columns: 1fr;
  }
}
</style>

